﻿using Core;
using System;

namespace g_gongjianta
{
    public class SkillObject : Core.Entity, IAwake<TblSkill.Conf>
    {
        public TblSkill.Conf Conf { get; private set; }
        public bool IsComplete { get; private set; }
        public int FrameCount { get; private set; }

        private int startFrame;

        private LifeCycleSystem lifeCycle;

        public void Awake(TblSkill.Conf t)
        {
            Conf = t;

            lifeCycle = Add<LifeCycleSystem>();
        }

        public override void Dispose()
        {
            if (IsDisposed) return;
            base.Dispose();

            Conf = null;
            lifeCycle = null;
        }

        public void Enter()
        {
            IsComplete = false;
            startFrame = SysTime.FrameCount;
            FrameCount = 0;

            //if(Entity is Duck)
            //{
            //    log.err($"Skill.Enter id={Conf.Id}");
            //}

            // Trigger(InstanceId, Conf);

            PollingFrameEvt();
        }

        public void Exit()
        {
            //if (Entity is Duck)
            //{
            //    log.err($"Skill.Exit id={Conf.Id}");
            //}
        }

        public void Tick()
        {
            if (IsComplete) return;

            var frame = SysTime.FrameCount - startFrame;
            if (frame == FrameCount) return;

            FrameCount = frame;

            PollingFrameEvt();

            if (FrameCount >= Conf.Duration)
            {
                IsComplete = true;
            }
        }

        private void PollingFrameEvt()
        {
            Trigger(Conf.BulletEvts, Trigger);
            // Trigger(Conf.SoundEvts, Trigger);
            // Trigger(Conf.ActionEvts, Trigger);
            // Trigger(Conf.EffectEvts, Trigger);
        }

        private void Trigger<T>(T[] evtArr, Action<long, TblSkill.Conf, T> trigger_func)
            where T : TblSkill.SkillEvt
        {
            if (evtArr is { Length: > 0 })
            {
                for (int i = 0; i < evtArr.Length; i++)
                {
                    var evt = evtArr[i];
                    if (evt.StartFrame == FrameCount)
                    {
                        trigger_func(InstanceId, Conf, evt);
                    }
                }
            }
        }

        // private void Trigger(long skill_srl, TblSkill.Conf skill_conf)
        // {
        //     // if (string.IsNullOrWhiteSpace(skill_conf.AnimName))
        //     // {
        //     //     return;
        //     // }
        //     //
        //     // Entity.Get<Sprite4DirAnimationComponent>()?.Play(skill_conf.AnimName);
        // }

        private void Trigger(long skill_srl, TblSkill.Conf skill_conf, TblSkill.BulletEvt conf)
        {
            var bullet = G.Factory.CreateWithParent<Bullet>(Entity);
            bullet.Awake(skill_srl, skill_conf, conf);

            if (conf.LifeType is 0 or 1)
            {
                lifeCycle.Mount(bullet.Main);
            }
            else
            {
                G.Get<LifeCycleSystem>().Mount(bullet.Main);
            }
        }

        // private void Trigger(long skill_srl, TblSkill.Conf skill_conf, TblSkill.ActionEvt evt_conf)
        // {
        //     //var comp = Entity.Get<SkillActionComponent>();
        //     //comp?.OnActionEvent(evt_conf);
        //
        //     var messenger = Entity.Get<EventComponent>();
        //     messenger?.Post(evt_conf.key, evt_conf);
        // }
        //
        // private void Trigger(long skill_srl, TblSkill.Conf skill_conf, TblSkill.SoundEvt evt_conf)
        // {
        //     // if (evt_conf.IsFootstep)
        //     // {
        //     //     Entity.Get<FootstepComponent>()?.OnMove(skill_srl);
        //     //     return;
        //     // }
        //
        //     var evt = Entity.Create<SoundEvent>();
        //     evt.Awake(skill_srl, skill_conf, evt_conf);
        //     G.Get<LifeCycleSystem>()?.Mount(evt);
        // }
        //
        // private void Trigger(long skill_srl, TblSkill.Conf skill_conf, TblSkill.EffectEvt evt_conf)
        // {
        //     // var evt = Entity.Create<Effect>();
        //     // evt.Awake(skill_srl, skill_conf, evt_conf);
        //     //
        //     // lifeCycle.Mount(evt.Get<LifeCycleComponent>());
        // }
    }
}